
# 从qtpy库的QtWidgets模块导入所有类
from qtpy.QtWidgets import *
# 从qtpy库导入QtCore和QtGui模块，其中QtGui未使用，后续可移除
from qtpy import QtCore, QtGui


class MouseButtonCaptureWidget(QPushButton):
    """
    MouseButtonCaptureWidget类继承自QPushButton，用于捕获鼠标按钮。
    当用户点击按钮后，可以捕获鼠标按钮事件，并通过信号发射捕获到的按钮信息。

    :ivar captured: 自定义信号，当捕获到鼠标按钮时发射，携带捕获到的鼠标按钮信息。
    """

    # 定义一个信号，当捕获到鼠标按钮时发射，携带捕获到的鼠标按钮对象
    captured = QtCore.Signal(object)

    def __init__(self, parent=None):
        """
        初始化MouseButtonCaptureWidget实例。

        :param parent: 父控件，默认为None。
        """
        # 调用父类QPushButton的构造函数
        super(MouseButtonCaptureWidget, self).__init__(parent)
        # 初始化当前捕获到的鼠标按钮为无按钮状态
        self._currentButton = QtCore.Qt.MouseButton.NoButton
        # 此处存在类型错误，self._currentButton.name 实际为 () -> str | None 类型，应为 str 类型
        self.setText(self._currentButton.name)
        # 标记是否正在捕获鼠标按钮
        self.bCapturing = False
        # 设置按钮为可勾选状态
        self.setCheckable(True)
        # 设置按钮的提示信息，告知用户按下Esc键可清除按钮设置，左键点击可开始捕获
        self.setToolTip(
            "<b>Esc</b> will set button to <u>NoButton</u> clear.<br><b>Left mouse button</b> will initiate capturing"
        )

    @property
    def currentButton(self):
        """
        获取当前捕获到的鼠标按钮。

        :return: 当前捕获到的鼠标按钮对象。
        """
        return self._currentButton

    @currentButton.setter
    def currentButton(self, btn):
        """
        设置当前捕获到的鼠标按钮，并更新按钮文本，停止捕获操作，发射捕获信号。

        :param btn: 要设置的鼠标按钮对象。
        """
        self._currentButton = btn
        # 此处存在类型错误，self._currentButton.name 实际为 () -> str | None 类型，应为 str 类型
        self.setText(self._currentButton.name)
        # 取消按钮的勾选状态
        self.setChecked(False)
        # 停止捕获鼠标按钮
        self.bCapturing = False
        # 发射捕获信号，携带新的鼠标按钮信息
        self.captured.emit(self._currentButton)

    def keyPressEvent(self, event):
        """
        处理键盘按键事件，当按下Esc键时，将当前鼠标按钮重置为无按钮状态。

        :param event: 键盘事件对象，包含按下的按键信息。
        """
        # 调用父类的键盘按键事件处理方法
        super(MouseButtonCaptureWidget, self).keyPressEvent(event)
        # 检查是否按下了Esc键，此处存在类 'Qt' 的未解析的特性引用问题
        if event.key() == QtCore.Qt.Key_Escape:
            # 将当前鼠标按钮设置为无按钮状态
            self.currentButton = QtCore.Qt.MouseButton.NoButton

    def mousePressEvent(self, event):
        """
        处理鼠标按下事件，根据当前是否正在捕获鼠标按钮进行相应操作。

        :param event: 鼠标事件对象，包含按下的鼠标按钮信息。
        """
        # 获取按下的鼠标按钮
        button = event.button()
        # 检查是否正在捕获鼠标按钮
        if self.bCapturing:
            # 若正在捕获，则将当前鼠标按钮设置为按下的按钮
            self.currentButton = button
        else:
            # 若未在捕获，检查是否按下的是左键且未在捕获状态
            if button == QtCore.Qt.MouseButton.LeftButton and not self.bCapturing:
                # 开始捕获鼠标按钮
                self.bCapturing = True
                # 设置按钮文本为 "capturing..."
                self.setText("capturing...")
                # 调用父类的鼠标按下事件处理方法
                super(MouseButtonCaptureWidget, self).mousePressEvent(event)


if __name__ == "__main__":
    import sys

    # 创建一个QApplication实例，用于管理应用程序的资源和事件循环
    a = QApplication(sys.argv)

    # 创建MouseButtonCaptureWidget实例
    w = MouseButtonCaptureWidget()
    # 显示窗口
    w.show()

    # 进入应用程序的事件循环，等待用户操作，直到窗口关闭
    sys.exit(a.exec_())